define([ 'require', 'jquery', 'game/math', 'game/objects/plane' ], function(require, $, math, plane) {
    return {

        __hexmap: [],

        __mouseover_hex_coords: null,

        __mousedown_coords: null,

        __mousedown_init_coords: null,

        init: function() {
            console.log("Initializing canvas");
            var _canvas = $('#canvas');
            this.canvas = _canvas[0];
            this.ctx = this.canvas.getContext("2d");
            this.translate = {
                x: 0,
                y: 0
            };
            _canvas.mousemove($.proxy(this.__mousemove, this));
            _canvas.mousedown($.proxy(this.__mousedown, this));
            _canvas.mouseup($.proxy(this.__mouseup, this));
            _canvas.mouseout($.proxy(this.__mouseout, this));
            this.plane = plane();
        },

        resize: function() {
            this.width = this.canvas.width = window.innerWidth;
            this.height = this.canvas.height = window.innerHeight;
            this.redraw();
        },

        redraw: function() {
            this.ctx.setTransform(1, 0, 0, 1, 0, 0);
            this.ctx.clearRect(0, 0, this.width, this.height);
            this.ctx.setTransform(1, 0, 0, 1, this.width / 2 + this.translate.x, this.height / 2 + this.translate.y);
            this.plane.draw();
        },

        __mousemove: function(event) {
            var rect = this.canvas.getBoundingClientRect();
            var coords = {
                x: event.clientX - rect.left,
                y: event.clientY - rect.top
            };
            this.__hexhover(coords);
            if (this.__mousedown_coords) {
                this.translate.x -= this.__mousedown_coords.x - coords.x;
                this.translate.y -= this.__mousedown_coords.y - coords.y;
                this.__mousedown_coords = coords;
                this.redraw();
            }
        },

        __get_hex_coords: function(coords) {
            return math.xy_to_axial(coords.x - this.width / 2 - this.translate.x, coords.y - this.height / 2 - this.translate.y);
        },

        __hexhover: function(coords) {
            var gc = this.__get_hex_coords(coords);
            var ogc = this.__mouseover_hex_coords;
            if (ogc == null || (ogc.x != gc.x || ogc.y != gc.y)) {
                if (ogc != null) {
                    var h = this.plane.gethex(ogc);
                    if (h != null) {
                        h.selected = false;
                        h.redraw_inner();
                    }
                }
                var h = this.plane.gethex(gc);
                if (h != null) {
                    h.selected = true;
                    h.redraw_inner();
                }
                this.__mouseover_hex_coords = gc;
            }
        },

        __mousedown: function(event) {
            var rect = this.canvas.getBoundingClientRect();
            this.__mousedown_init_coords = this.__mousedown_coords = {
                x: event.clientX - rect.left,
                y: event.clientY - rect.top
            };
        },

        __mouseup: function(event) {
            var rect = this.canvas.getBoundingClientRect();
            var coords = {
                x: event.clientX - rect.left,
                y: event.clientY - rect.top
            };
            var init_coords = this.__mousedown_init_coords;
            if (init_coords && math.dist_xy(coords, init_coords) < 5) {
                var hc = this.__get_hex_coords(coords);
                var h = this.plane.gethex(hc);
                if (h != null) {
                    h.onclick();
                }
            }
            this.__mousedown_coords = this.__mousedown_init_coords = null;
        },

        __mouseout: function(event) {
            this.__mousedown_coords = this.__mousedown_init_coords = null;
        }

    };
});
